package cn.schoolwow.quickdao.module.database.dml.kit;

import cn.schoolwow.quickdao.module.database.dml.common.domain.ManipulationOption;
import cn.schoolwow.quickdao.module.database.dml.existQuery.kit.DatabaseManipulationExistQueryImpl;
import cn.schoolwow.quickdao.module.database.dml.instance.kit.DatabaseManipulationInstanceImpl;
import cn.schoolwow.quickdao.module.database.dml.json.kit.DatabaseManipulationJSONImpl;
import cn.schoolwow.quickdao.module.database.dml.option.kit.DatabaseManipulationOptionImpl;
import cn.schoolwow.quickdao.module.database.dml.parent.kit.DatabaseManipulationParentImpl;
import cn.schoolwow.quickflow.QuickFlow;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class DatabaseManipulationInvocationHandler implements InvocationHandler {
    private Object[] interfaceInstanceArray;

    public DatabaseManipulationInvocationHandler(QuickFlow quickFlow) {
        ManipulationOption manipulationOption = new ManipulationOption();
        quickFlow.putContextThreadLocalInstanceData(manipulationOption);

        interfaceInstanceArray = new Object[]{
                new DatabaseManipulationParentImpl(quickFlow),
                new DatabaseManipulationOptionImpl(quickFlow),
                new DatabaseManipulationExistQueryImpl(quickFlow),
                new DatabaseManipulationInstanceImpl(quickFlow),
                new DatabaseManipulationJSONImpl(quickFlow),
        };
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String interfaceName = method.getDeclaringClass().getSimpleName();
        for(Object interfaceInstance:interfaceInstanceArray){
            Class interfaceClass = interfaceInstance.getClass().getInterfaces()[0];
            if(interfaceClass.getSimpleName().equalsIgnoreCase(interfaceName)){
                try {
                    return method.invoke(interfaceInstance, args);
                }catch (InvocationTargetException e){
                    Throwable targetException = e.getTargetException();
                    throw targetException;
                }
            }
        }
        throw new IllegalAccessError("不支持调用该方法!方法名:"+method.getName());
    }
}
